package com.godofgamblers.hotelmanagementsystem.service.imp;

import com.godofgamblers.hotelmanagementsystem.dto.OfflinePriceDto;
import com.godofgamblers.hotelmanagementsystem.dto.TimeDto;
import com.godofgamblers.hotelmanagementsystem.handler.SystemSettingHandler;
import com.godofgamblers.hotelmanagementsystem.mapper.*;
import com.godofgamblers.hotelmanagementsystem.pojo.*;
import com.godofgamblers.hotelmanagementsystem.service.Check_In_InfoService;
import com.godofgamblers.hotelmanagementsystem.util.DateUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.UUID;

@Service
public class Check_In_InfoServiceImp implements Check_In_InfoService {

    @Autowired
    private Check_In_InfoMapper check_in_infoMapper;
    @Autowired
    private Order_ItemMapper order_item_Mapper;
    @Autowired
    private OrderMapper orderMapper;
    @Autowired
    private Room_typeMapper room_typeMapper;
    @Autowired
    private RoomMapper roomMapper;
    @Autowired
    private UserMapper userMapper;

    /**
     * 线上预定开单
     * @param check_in_infoPojo 入住信息pojo类
     * @return String
     */
    @Override
    public String addCheckInInfo(Check_In_Info check_in_infoPojo) {
        String result="开单失败！";
        //检查房间状态
        Integer roomstate = roomMapper.checkRoomstateByRoomNum(check_in_infoPojo.getRoom_num());
        if(roomstate==1){
            result = check_in_infoPojo.getRoom_num()+"号房间正在使用中";
            return result;
        }
        if(roomstate==2){
            result = check_in_infoPojo.getRoom_num()+"号房间正在修理中";
            return result;
        }
        //检查订单状态
        Integer orderItemState = order_item_Mapper.findOrderItemStateByOrderItemId(check_in_infoPojo.getOrder_item_id());
        //0=未支付 1=(线上预定)未使用 2=已使用,3=(线上预定)线下给钱，4=用户取消,5=已完成
        if(orderItemState==2){
            //查询使用该订单项入住的入住人信息
            String name = check_in_infoMapper.findActualNameByOrderItemId(check_in_infoPojo.getOrder_item_id());
            result = "该订单项已被"+name+"顾客使用";
            return result;
        }
        if(orderItemState==4){
            result = "该订单项已取消";
            return result;
        }
        if(orderItemState==5){
            result = "该订单项已完成";
            return result;
        }
        //通过订单项id查询订单id
        int order_id = order_item_Mapper.findOrderId(check_in_infoPojo.getOrder_item_id());
        //查询订单状态是否为已支付
        int order_state = orderMapper.findOrderStateByOrderId(order_id);
        //0=未支付 1=已支付 2=已取消 3=已失效
        if(order_state == 0){
            result = "该订单未付款！";
            return result;
        }
        if(order_state==1){
            //获取入住时间
            check_in_infoPojo.setCheck_in_time(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
            //将入住信息插入check_in_info表
            int addCheckInInfo = check_in_infoMapper.addCheckInInfo(check_in_infoPojo);
            //插入成功
            if(addCheckInInfo>0){
                //修改订单项状态为2（已使用）
                Order_item order_itemPojo=new Order_item();
                //传入订单项id
                order_itemPojo.setOrder_item_id(check_in_infoPojo.getOrder_item_id());
                //设置订单项状态2（已使用）
                order_itemPojo.setOrder_item_state(2);
                //根据订单项id修改订单项状态
                int updateOrderItemState=order_item_Mapper.updateState(order_itemPojo);
                //修改房间状态
                Room room = new Room();
                room.setRoom_state(1);
                room.setRoom_num(check_in_infoPojo.getRoom_num());
                int updateRoomState = roomMapper.checkOutupdateRoomState(room);
                result = "开单成功！";
            }
        }else {
            result="请先付款！";
        }
        return result;
    }

    /**
     * 计算线下价格
     * @param offlinePriceDto   线下价格dto类，封装计划入住时间、计划退房时间、房间类型id、会员折扣、全场折扣
     * @return  OfflinePriceDto  价格、
     */
    @Override
    public OfflinePriceDto offlineShowRooms(OfflinePriceDto offlinePriceDto) {
        //创建一个Room_type用于存放全场折扣
        Room_Type room_type = new Room_Type();
        //创建一个Room用于传递房间类型id和房间状态
        Room room=new Room();
        //判断是否使用全场折扣
        if(!SystemSettingHandler.all_discount){
            //如果不使用全场折扣，将全场折扣设置为1
            offlinePriceDto.setAllDiscount(new BigDecimal(1));
        }else{
            //如果使用全场折扣，从数据库中查询出全场折扣
            room_type=room_typeMapper.findAllDiscountAndPrice(offlinePriceDto.getRoom_type_id());
            //将全场折扣设置为查询到的值
            offlinePriceDto.setAllDiscount(room_type.getRoom_type_discount());
        }
        //如果用户不存在，将会员折扣设置为1
        if(offlinePriceDto.getLevel_discount()==null){
            offlinePriceDto.setLevel_discount(new BigDecimal(1));
        }
        //计算总入住天数
        long day= DateUtil.calculateDays(offlinePriceDto.getStartTime(),offlinePriceDto.getEndTime());
        //查询房间价格
        room_type = room_typeMapper.findAllDiscountAndPrice(offlinePriceDto.getRoom_type_id());
        //价格=房间类型价格*总入住天数*全场折扣*会员折扣
        BigDecimal price = room_type.getRoom_type_price().multiply(new BigDecimal(day)).multiply(offlinePriceDto.getAllDiscount()).multiply(offlinePriceDto.getLevel_discount());
        //判断是否取整
        BigDecimal pricefact=new BigDecimal(0);
        if(SystemSettingHandler.round_flag){
            //取整，将价格四舍五入到个位
            pricefact = price.setScale(0,BigDecimal.ROUND_HALF_UP);
        }else {
            //不取整,价格四舍五入保留2位
            pricefact=price.setScale(2,BigDecimal.ROUND_HALF_UP);
        }
        //新建一个list用于存放房间信息
        List<Room> rooms=new ArrayList<Room>();
        //将房间类型id和房间状态封装进Room对象中
        room.setRoom_type_id(offlinePriceDto.getRoom_type_id());
        room.setRoom_state(offlinePriceDto.getRoom_state());
        //根据房间类型及房间状态查询房间信息
        rooms = roomMapper.findroomsByRoom_typeAndRoomState(room);

        //将计算出的价格和查询到的房间信息封装进要返回的OfflinePriceDto对象中
        offlinePriceDto.setRooms(rooms);
        offlinePriceDto.setPrice(pricefact);

        return offlinePriceDto;
    }

    /**
     * 线下开单
     * @param user 用户pojo类,传入用户id
     * @param offlinePriceDto  线下价格pojo类，传入价格、房间类型id、计划入住时间、计划离店时间
     * @param check_in_info 入住信息pojo类、传入房间号、入住人姓名、身份证、实际入住时间
     * @return String 操作结果
     */
    @Override
    public String offlineBooking(User user, OfflinePriceDto offlinePriceDto, Check_In_Info check_in_info) {
        String result="开单失败！";
        //检查房间状态
        Integer roomstate = roomMapper.checkRoomstateByRoomNum(check_in_info.getRoom_num());
        if(roomstate==1){
            result = check_in_info.getRoom_num()+"号房间正在使用中";
            return result;
        }
        if(roomstate==2){
            result = check_in_info.getRoom_num()+"号房间正在修理中";
            return result;
        }
        //通过房间类型id查找最大库存及房间类型名称
        Room_Type room_type = room_typeMapper.offlineFindMaxStockByRoomTypeId(offlinePriceDto.getRoom_type_id());
        //通过房间类型id查找已使用房间
        int usedRoomNum = order_item_Mapper.offlineFindUsedRoomNumByRoomTypeId(offlinePriceDto);
        //判断当前房间类型有无库存
        if (room_type.getRoom_type_stock()<usedRoomNum+1){
            //如果没有库存
            result = room_type.getRoom_type_name()+"库存不足";
            return result;
        }

        //如果库存充足
        //添加订单
        //生成订单编号
        String order_num = UUID.randomUUID().toString().replaceAll("-","");
        //设置要插入的订单信息
        Order order = new Order();
        //订单编号
        order.setOrder_num(order_num);
        //user_id
        order.setUser_id(userMapper.findUser_idByAccount(user.getUser_account()));
        //订单价格
        order.setTotal_price(offlinePriceDto.getPrice());
        //订单创建时间(当前时间)
        order.setOrder_time(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
        //支付方式（线下支付）
        order.setPay_way(1);
        //订单状态（已支付）
        order.setOrder_state(1);
        //插入订单
        int insertOrderRow = orderMapper.offlineAddOrder(order);
        if(insertOrderRow<=0){
            result = "订单添加失败，请联系管理员！";
            return result;
        }


        //添加订单项
        //设置要插入的订单项信息
        Order_item order_item = new Order_item();
        //订单项编号
        String order_item_num = UUID.randomUUID().toString().replaceAll("-","");
        order_item.setOrder_item_num(order_item_num);
        //订单id
        order_item.setOrder_id(orderMapper.offlineFindOrderIdByOrderNum(order_num));
        //房间类型id
        order_item.setRoom_type_id(offlinePriceDto.getRoom_type_id());
        //计划入住时间
        order_item.setPlan_stay_time(offlinePriceDto.getStartTime());
        //计划退房时间
        order_item.setPlan_leave_time(offlinePriceDto.getEndTime());
        //订单项状态2（已使用）
        order_item.setOrder_item_state(2);
        //插入订单项
        int insertOrderItemRow= order_item_Mapper.offlineAddOrderItem(order_item);
        if(insertOrderItemRow<=0){
            result = "订单项添加失败，请联系管理员！";
            return result;
        }

        //添加入住信息
        //设置要插入的入住信息
        //房间编号、入住人姓名、身份证号、计划入住时间由前端传入
        //订单项编号
        check_in_info.setOrder_item_id(order_item_Mapper.offlineFindOrderItemIdByOrderItemNum(order_item_num));
        check_in_info.setCheck_in_time(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
        //插入入住信息
        int insertCheckInInfoRow = check_in_infoMapper.addCheckInInfo(check_in_info);
        if(insertCheckInInfoRow<=0){
            result = "入住信息添加失败，请联系管理员！";
            return result;
        }
        //根据房间编号修改房间状态
        int updateRoomStateRow = roomMapper.offlineUpdateRoomStateByRoomNum(check_in_info.getRoom_num());
        if(updateRoomStateRow<=0){
            result = "房间状态修改失败，请联系管理员！";
            return result;
        }
        result = "操作成功！";
        return result;
    }

    /**
     * 退房
     * @param room 传入房间编号
     * @return 操作结果
     */
    @Override
    public String checkOut(Room room) {
        String result = "操作失败！";
        //写入退房时间
        Check_In_Info check_in_info = new Check_In_Info();
        //房间编号
        check_in_info.setRoom_num(room.getRoom_num());
        //退房时间
        check_in_info.setCheck_out_time(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
        //查询订单项id
        Integer order_item_id = check_in_infoMapper.checkOutFindOrderItem(check_in_info);
        //插入退房时间
        int addCheckOutTime = check_in_infoMapper.updateCheckOutTime(check_in_info);
        if(addCheckOutTime<=0){
            result = "入住信息插入失败，请联系管理员！";
            return result;
        }

        //修改订单项状态为5（已完成）
        Order_item order_item = new Order_item();
        //订单项id
        order_item.setOrder_item_id(order_item_id);
        order_item.setOrder_item_state(5);
        //修改状态
        int updateOrderItemState = order_item_Mapper.updateState(order_item);
        if(updateOrderItemState<=0){
            result = "订单项状态修改失败，请联系管理员！";
            return result;
        }

        //修改房间状态为3（打扫中）
        room.setRoom_state(3);
        int updateRoomState = roomMapper.checkOutupdateRoomState(room);
        if(updateRoomState<=0){
            result = "房间状态修改失败，请联系管理员！";
            return result;
        }

        //修改积分
        //判断此订单是否以计算积分
        //查询订单id
        Integer order_id = order_item_Mapper.findOrderId(order_item_id);
        //查询此订单是否已计算积分、用户id及价格
        Order order = orderMapper.findCreditCountAndPriceByOrderId(order_id);
        //判断是否计算积分
        if(order.getCredit_count()==0&&order.getUser_id()!=null){
            System.out.println("*********************");
            System.out.println("积分");
            //如果未计算，则计算积分
            User user = new User();
            //查询该用户积分
            int credit = userMapper.findUserCreditByUser_id(order.getUser_id());
            //设置需要传入的积分
            user.setUser_credit(credit+order.getTotal_price().intValue());
            //设置用户id
            user.setUser_id(order.getUser_id());
            int updateCredit = userMapper.checkOutUpdateCridit(user);
            orderMapper.updateCreditCountByOrderId(order_id);
        }
        result = "操作成功！";

        return result;
    }

    /**
     * 显示房间信息
     * @param room  传入房间类型id及状态
     * @return List<Room>
     */
    @Override
    public OfflinePriceDto operateShowRoom(Room room) {
        OfflinePriceDto offlinePriceDto = new OfflinePriceDto();
        if(room.getRoom_type_id()==null){
            List<Room> rooms = new ArrayList<Room>();
            offlinePriceDto.setRooms(rooms);
        }else{
            //根据传入的房间信息和状态动态查询房间信息
            List<Room> rooms = roomMapper.findroomsByRoom_typeAndRoomState(room);
            //查找对应的房间类型
            Room_Type room_type = room_typeMapper.findAllDiscountAndPrice(room.getRoom_type_id());
            offlinePriceDto.setRooms(rooms);
            if(room_type!=null){
                offlinePriceDto.setRoom_type_name(room_type.getRoom_type_name());
            }
        }
        return offlinePriceDto;
    }

    /**
     * 显示所有的房间类型
     * @return
     */
    @Override
    public List<Room_Type> findRoomTypeInfos() {
        List<Room_Type> room_types = room_typeMapper.findRoomTypeInfos();
        return room_types;
    }

    @Override
    public TimeDto findTime(Integer order_item_id) {
        return check_in_infoMapper.findTime(order_item_id);
    }


}
